package errcode

import (
	"fmt"
	"log"
	"net/http"
)

// 错误码
type Error struct {
	code    int      `json:"code"`    // 状态码
	msg     string   `json:"msg"`     // 错误信息
	details []string `json:"details"` // 错误详情
}

// 错误码集合
var codes = map[int]string{}

// 实例化一个错误
func NewError(code int, msg string) *Error {
	if _, ok := codes[code]; ok {
		log.Fatalf("错误码: %d 已经存在，请更换", code)
	}
	codes[code] = msg
	return &Error{
		code: code,
		msg:  msg,
	}
}

func (e *Error) Error() string {
	return fmt.Sprintf("错误码：%d, 错误信息：%s", e.Code(), e.Msg())
}

func (e *Error) Code() int {
	return e.code
}

func (e *Error) Msg() string {
	return e.msg
}

func (e *Error) Details() []string {
	return e.details
}

// 将错误详情加入到错误中
func (e *Error) WithDetails(details ...string) *Error {
	e.details = []string{}
	for _, d := range details {
		e.details = append(e.details, d)
	}
	return e
}

// 错误码对应的http状态
func (e *Error) StatusCode() int {
	switch e.Code() {
	case Success.Code():
		return http.StatusOK
	case SerVerError.Code():
		return http.StatusInternalServerError
	case InvalidParams.Code():
		return http.StatusBadRequest
	case UnauthorizedAuthNotExist.Code():
		fallthrough
	case UnauthorizedTokenError.Code():
		fallthrough
	case UnauthorizedTokenTimeout.Code():
		return http.StatusUnauthorized
	case UnauthorizedTokenGenerate.Code():
		fallthrough
	case TooManyRequests.Code():
		return http.StatusTooManyRequests
	case ErrorDictExistFail.Code():
		return http.StatusForbidden
	}
	return http.StatusInternalServerError
}
